package com.tansun.ruledata.controller;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.drools.core.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tansun.rule.config.AppConfiguration;
import com.tansun.rule.utils.IOUtils;
import com.tansun.rule.utils.JsonMessage;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.RuleMapAndJsonUtils;
import com.tansun.rule.utils.Uuid;
import com.tansun.ruledata.data.service.BussinessSynchService;
import com.tansun.ruledata.data.service.RuleResourceLoadService;
import com.tansun.ruledata.entity.ReqBody;
import com.tansun.ruledata.entity.RuleDataExcuterParam;
import com.tansun.ruledata.entity.RuleDataParam;
import com.tansun.ruledata.entity.RuleExcuterParam;
import com.tansun.ruledata.service.RuleDataBusinessService;

@Controller
@RequestMapping(value = "/ruleDataService")
public class RuleDataServiceController extends HttpServlet{
	private Logger log = LoggerFactory.getLogger(this.getClass());
	private Logger bankLog = LoggerFactory.getLogger("fcos_statis");
	@Autowired
	private RuleDataBusinessService ruleDataBusinessService;
	@Autowired
	private RuleResourceLoadService ruleResourceLoadService;
	@Autowired
	private BussinessSynchService bussinessSynchService;


	
	/**
	 * 规则执行接口
	 * 
	 * @param projectCode
	 * @param enterPoint
	 * @param businessInput
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/ruleEngineService", method = RequestMethod.POST)
	public @ResponseBody String ruleEngineService(HttpServletRequest request, HttpServletResponse response,
			ModelMap map) throws Exception {
		// long start = System.currentTimeMillis();
		String projectCode = request.getParameter("projectCode");
		String enterPoint = request.getParameter("enterPoint");
		String businessInput = request.getParameter("businessInput");
		String type = request.getParameter("type");
		if (StringUtils.isEmpty(type)) {
			type = "json";
		}
		String result = ruleDataBusinessService.ruleEngineService(projectCode, enterPoint, type, businessInput);
		// log.info("CertificationBean-调用服务时间：" + (System.currentTimeMillis() -
		// start));
		return result;
	}
	/**
	 * 规则执行接口-卡中心
	 * 
	 * @param request
	 * @param response
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/ruleEngineService_vo", method = RequestMethod.POST)
	public @ResponseBody String ruleEngineService_vo(@RequestBody RuleExcuterParam param) {
		// String result =
		// ruleDataBusinessService.ruleEngineService(param.getProjectCode(),
		// param.getEnterPoint(), "json", param.getBusinessInput());
		Map<String, Object> businessInputMap = (Map<String, Object>) JSON.parse(param.getBusinessInput().toString());
		Map<String, Object> resultMap = ruleDataBusinessService.ruleEngineService(param.getProjectCode(),
				param.getEnterPoint(), businessInputMap);
		return JSON.toJSONString(resultMap);
	}

	/**
	 * 获取规则流使用的参数
	 * 
	 * @param projectCode
	 * @param enterPoint
	 * @return
	 */
	@RequestMapping("/ruleFlowParamInfo")
	public @ResponseBody JsonMessage ruleFlowParamInfo(String projectCode, String enterPoint) {
		JsonMessage ret = new JsonMessage();
		try {
			String result = ruleDataBusinessService.ruleFlowParamInfo(projectCode, enterPoint);
			ret.setData(result);
		} catch (Exception e) {
			// TODO: handle exception
			log.error(e.getMessage(), e);
			ret.setResult(false);
			ret.setMessage(IOUtils.getStackTraceMsg(e));
		}
		return ret;
	}
	@RequestMapping({ "/ruleProjectParamInfo" })
	public @ResponseBody String ruleProjectParamInfo() {
		try {
			return this.ruleDataBusinessService.ruleProjectParamInfo();
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 规则执行日志查询接口
	 * 
	 * @param request
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@RequestMapping({ "/ruleExecutionLog" })
	public @ResponseBody String ruleExecutionLog(HttpServletRequest request) {
		String projectCode = request.getParameter("projectCode");
		try {
			return this.ruleDataBusinessService.ruleExecutionLogList(projectCode);
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 规则执行日志项目详情查询接口
	 * 
	 * @param request
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@RequestMapping({ "/ruleExecutionLogDetails" })
	public @ResponseBody String ruleExecutionLogDetails(HttpServletRequest request) {
		String projectCode = request.getParameter("projectCode");
		String ruleFlowId = request.getParameter("ruleFlowId");
		try {
			return this.ruleDataBusinessService.ruleExecutionLogDetails(projectCode, ruleFlowId);
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
		}
		return null;
	}
	
	
	/**
	 * 联机部署方式调用
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	
	@RequestMapping(value = "/ruleDataServiceBcm_new", method = RequestMethod.POST)
	public @ResponseBody Map<String, Object> ruleEngineServiceBcm_vo(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		String uuidStr = Uuid.createId();
		long start = System.currentTimeMillis();
		String logSuccessBoo = null;
		String logException = null;
		String logExceptionType = null;
	    MDC.put("processId", uuidStr);
		try{
			//获取JSON数据
			String REQ_MESSAGE = request.getParameter("REQ_MESSAGE");
			log.info("总行入参报文 -REQ_MESSAGE：" + REQ_MESSAGE);
			
			if(null == REQ_MESSAGE || REQ_MESSAGE.equals("")){
				map.put("RSP_HEAD", new HashMap<String, Object>() {
					{
						put("ERROR_MESSAGE", "格式不正确");// 错误信息
					}
				});	
				
			} else {
				//JSON转对象
				RuleDataParam ruleDataParam =JSONObject.parseObject(REQ_MESSAGE, RuleDataParam.class);
				//获取Body里面JSON数据转对应的对象
				ReqBody  reqBody  =  ruleDataParam.getReqBody();
				Map<String, Object> businessInputMap = reqBody.getBusinessInput();
				Map<String, Object> requestMap = ruleDataBusinessService.initRuleParamMap(reqBody.getProjectCode(), reqBody.getEnterPoint(), businessInputMap);
				Map<String, Object> resultMap = ruleDataBusinessService.ruleEngineService_ruleExe(reqBody.getProjectCode(),
						reqBody.getEnterPoint(), requestMap,uuidStr);
				String isSuccess ="";
				Map<String,Object>  resMap  = new HashMap<>();
				resMap.put("projectCode", reqBody.getProjectCode());
				resMap.put("enterPoint", reqBody.getEnterPoint());
				resMap.put("businessInput", resultMap);
				Object  obj =resultMap.get("SystemOutInfo");
				Map<String,Object>  rspMap = null;
				if (obj != null) {
				    rspMap =(Map) obj;
					if (rspMap != null) {
					   isSuccess=(String) rspMap.get("isSuccess");
					}					
				}
				log.info("规则引擎返回结果集- requestMap：" + resultMap);
				log.info("规则引擎返回成功标识 -isSuccess：" + isSuccess);
				Map<String,Object>  resHedMap  = new  HashMap<>();
				resHedMap.put("TRAN_SUCCESS", isSuccess);
				resHedMap.put("TRACE_NO", uuidStr);
				if (isSuccess.equals(Uuid.TRAN_SUCCESS)) {				
					map.put("RSP_HEAD",resHedMap);
					map.put("RSP_BODY", resMap);
				} else {
					String exceptionType = (String) rspMap.get("exceptionType");
					String exception = (String) rspMap.get("exception");
					logExceptionType = exceptionType;
					logException = exception;
					resHedMap.put("ERROR_CODE ", exceptionType);// 错误码
					resHedMap.put("ERROR_MESSAGE", exception);// 错误信息
					map.put("RSP_HEAD", resHedMap);
					map.put("RSP_BODY", resMap);
				}
			}
			logDataService(start, logSuccessBoo, logExceptionType, logException, uuidStr);
			log.info("规则引擎返回封装结果集-map：" + JSON.toJSONString(map));
		    MDC.remove("processId");

		}catch (Exception e) {
			map.put("TRAN_SUCCESS", "0");// 交易易是否成功
			map.put("TRACE_NO", uuidStr);// 跟踪号(随机生成数)
			map.put("ERROR_CODE ", "500500");// 错误码
			map.put("ERROR_MESSAGE", e.getMessage());// 错误信息
			log.info("规则引擎返回错误异常信息-map：" + JSON.toJSONString(map));
			e.printStackTrace();
		}
		return map;

	}
	
	private void  logDataService(Long startTime, String successBoo, String logExceptionType,String logException,String uuidStr) {
        //结束时间
        long endTime = System.currentTimeMillis();

        long serviceTime = endTime - startTime;

        StringBuilder statis = new StringBuilder();

        String sts = new Timestamp(startTime).toString();
        //交易开始时间戳
        statis.append(sts);
        statis.append("||");
        String ets = new Timestamp(endTime).toString();
        //交易结束时间戳
        statis.append(ets);
        statis.append("||");
        //交易耗时（秒）
        statis.append(serviceTime);
        statis.append("||");
        //PROCESS TODO
        statis.append(uuidStr);
        statis.append("||");
        //交易是否成功、错误码
        String status = "";
        String errorMsg = "";
        if(null == successBoo) {
        	successBoo = "3";
        }
        
        if (successBoo.equals(Uuid.TRAN_SUCCESS)) {
        	statis.append("SUCCESS||null");
            status = "SUCCESS";
        } else {
            errorMsg = logException;
            status = "FAILED";
            statis.append("FAILED||" + errorMsg);
        }
        //错误信息
        bankLog.info(statis.toString());
    }


	/**
	 * 联机部署方式调用
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	/*@RequestMapping(value = "/ruleDataServiceBcm_vo", method = RequestMethod.POST)
	public @ResponseBody Map<String, Object> ruleEngineServiceBcm_vo(@RequestBody RuleDataParam ruleDataParam)
			throws Exception {
		RuleDataExcuterParam param = JSONObject.parseObject(JSON.toJSONString(ruleDataParam.getReqBody()),RuleDataExcuterParam.class);
		Map<String, Object> businessInputMap = JSONObject.toJavaObject(param.getBusinessInput(), Map.class);
		Map<String, Object> requestMap = initRequest(param.getProjectCode(), businessInputMap);
		Map<String, Object> resultMap = ruleDataBusinessService.ruleEngineService(param.getProjectCode(),
				param.getEnterPoint(), requestMap);
		RuleMapAndJsonUtils.mapConverJson_1(resultMap, businessInputMap);
		param.setBusinessInput((JSONObject) JSONObject.parse(JSON.toJSONString(businessInputMap)));
		businessInputMap = null;
		resultMap = null;

		// 规则引擎返回成功标识
		String isSuccess = (String) param.getBusinessInput().getJSONObject("SystemOutInfo").get("isSuccess");
		Map<String, Object> map = new HashMap<String, Object>();
		if (isSuccess.equals(Uuid.TRAN_SUCCESS)) {
			map.put("RSP_HEAD", new HashMap<String, Object>() {
				{
					put("TRAN_SUCCESS", isSuccess);// 交易易是否成功
					put("TRACE_NO", Uuid.createId());// 跟踪号(随机生成数)

				}
			});
			map.put("RSP_BODY", param);
		} else {
			String exceptionType = (String) param.getBusinessInput().getJSONObject("SystemOutInfo").get("exceptionType");
			String exception = (String) param.getBusinessInput().getJSONObject("SystemOutInfo").get("exception");
			map.put("RSP_HEAD", new HashMap<String, Object>() {
				{
					put("TRAN_SUCCESS", isSuccess);// 交易易是否成功
					put("TRACE_NO", Uuid.createId());// 跟踪号(随机生成数)
					put("ERROR_CODE ", exceptionType);// 错误码
					put("ERROR_MESSAGE", exception);// 错误信息

				}
			});
			map.put("RSP_BODY", param);
		}

		return map;

	}*/

	/**
	 * 离线方式部署调用
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/ruleDataServiceBcm_vo2", method = RequestMethod.POST)
	public @ResponseBody Map<String, Object> ruleEngineServiceBcm_tmp_vo(@RequestBody RuleDataParam ruleDataParam)
			throws Exception {
		RuleDataExcuterParam param = JSONObject.parseObject(JSON.toJSONString(ruleDataParam.getReqBody()),RuleDataExcuterParam.class);
		Map<String, Object> businessInputMap = JSONObject.toJavaObject(param.getBusinessInput(), Map.class);
//		Map<String, Object> requestMap = initRequest(param.getProjectCode(), businessInputMap);
		Map<String, Object> requestMap = ruleDataBusinessService.initRuleParamMap(param.getProjectCode(), param.getEnterPoint(), businessInputMap);
		Map<String, Object> resultMap = ruleDataBusinessService.ruleEngineService(param.getProjectCode(),
				param.getEnterPoint(), requestMap);
		RuleMapAndJsonUtils.mapConverJson_1(resultMap, businessInputMap);
		param.setBusinessInput((JSONObject) JSONObject.parse(JSON.toJSONString(businessInputMap)));
		businessInputMap = null;
		resultMap = null;
		// 规则引擎返回成功标识
		String isSuccess = (String) param.getBusinessInput().getJSONObject("SystemOutInfo").get("isSuccess");
		Map<String, Object> map = new HashMap<String, Object>();
		if (isSuccess.equals(Uuid.TRAN_SUCCESS)) {
			map.put("RSP_HEAD", new HashMap<String, Object>() {
				{
					put("TRAN_SUCCESS", isSuccess);// 交易易是否成功
					put("TRACE_NO", Uuid.createId());// 跟踪号(随机生成数)

				}
			});
			map.put("RSP_BODY", param);
		} else {
			String exceptionType = (String) param.getBusinessInput().getJSONObject("SystemOutInfo").get("exceptionType");
			String exception = (String) param.getBusinessInput().getJSONObject("SystemOutInfo").get("exception");
			map.put("RSP_HEAD", new HashMap<String, Object>() {
				{
					put("TRAN_SUCCESS", isSuccess);// 交易易是否成功
					put("TRACE_NO", Uuid.createId());// 跟踪号(随机生成数)
					put("ERROR_CODE ", exceptionType);// 错误码
					put("ERROR_MESSAGE", exception);// 错误信息

				}
			});
			map.put("RSP_BODY", param);
		}
		return map;
	}

	private Map<String, Object> initRequest(String projectCode, Map<String, Object> businessInputMap) throws Exception {
		Map<String, MClass> metaMap = AppConfiguration.RuleProjMetaMap.get(projectCode);
		if (metaMap == null || metaMap.isEmpty()) {
			this.ruleResourceLoadService.loadProjectDataMapping(projectCode);
			metaMap = AppConfiguration.RuleProjMetaMap.get(projectCode);


		}
		Map<String, Object> insertMap = RuleMapAndJsonUtils.jsonCoverMap(businessInputMap, metaMap,false);
		return insertMap;
	}

}
